import ipaddress
import re
import excel

# 定义函数calculate_ip_info，用于计算给定IP地址段的相关信息，包括第一个可用地址、最后一个可用地址、可用地址数量、网络地址、广播地址。
def calculate_ip_info(ip_str):
    """
    计算给定IP地址段的相关信息，包括第一个可用地址、最后一个可用地址、可用地址数量、网络地址、广播地址。

    参数：
    ip_str (str)：IP地址段的字符串表示，格式如 "136.48.21.2/25"

    返回：
    dict：包含相关IP地址信息的字典，键分别为 'first_usable_ip'、'last_usable_ip'、'num_usable_ips'、
          'network_address'、'broadcast_address'、'input_ip_str'、'subnet_mask_decimal'、'subnet_mask_cidr'、
          'network_with_mask'，对应的值分别为相应的IPv4Address类型的对象或对应的字符串表示形式，
          'input_ip_str' 对应原输入的IP地址段字符串，
          'subnet_mask_decimal' 对应子网掩码的点分十进制表示形式，
          'subnet_mask_cidr' 对应子网掩码的CIDR表示的位数形式，
          'network_with_mask' 对应网络地址与掩码位的组合表示形式（类似 x.x.x.x/y）。

    异常处理：
    如果输入的IP地址段字符串格式不符合规范要求，函数将返回包含错误信息的字典，其中键 'error' 对应的值为具体的错误提示内容。
    """
    # 定义正则表达式，用于简单校验IP地址段格式是否符合 x.x.x.x/y 的形式
    pattern = r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$'
    if not re.match(pattern, ip_str):
        return {'error': '输入的IP地址段格式不符合规范，请确保格式为 x.x.x.x/y 的形式'}

    try:
        network = ipaddress.IPv4Network(ip_str, strict=False)
        first_usable_ip = network.network_address + 1
        last_usable_ip = network.broadcast_address - 1
        num_usable_ips = network.num_addresses - 2

        # 获取子网掩码的点分十进制表示形式
        subnet_mask_decimal = str(network.netmask)
        # 获取子网掩码的CIDR表示的位数形式（即IP地址段中 / 后面的数字）
        subnet_mask_cidr = network.prefixlen

        # 组合网络地址与掩码位的表示形式
        network_with_mask = f"{network.network_address}/{subnet_mask_cidr}"

        return {
            'first_usable_ip': first_usable_ip,
            'last_usable_ip': last_usable_ip,
            'num_usable_ips': num_usable_ips,
            'network_address': network.network_address,
            'broadcast_address': network.broadcast_address,
            'input_ip_str': ip_str,
            'subnet_mask_decimal': subnet_mask_decimal,
            'subnet_mask_cidr': subnet_mask_cidr,
            'network_with_mask': network_with_mask
        }
    except ValueError as e:
        return {'error': f'解析IP地址段时出现错误: {str(e)}'}

# 定义函数convert_mask，用于在子网掩码的点分十进制表示和CIDR表示法之间进行互相转换。
def convert_mask(mask):
    """
    在子网掩码的点分十进制表示和CIDR表示法之间进行互相转换。

    参数：
    mask (str): 要转换的子网掩码，可以是点分十进制格式（例如 "255.255.255.0"）或者CIDR格式（例如 "24"）。

    返回：
    str: 如果输入是点分十进制格式，则返回对应的CIDR格式；如果输入是CIDR格式，则返回对应的点分十进制格式。
    如果输入的格式不符合要求，返回 "输入格式不正确，请检查"。
    """
    # 校验点分十进制格式
    if '.' in mask:
        parts = mask.split('.')
        if len(parts)!= 4:
            return "输入格式不正确，请检查"
        for part in parts:
            if not part.isdigit() or int(part) < 0 or int(part) > 255:
                return "输入格式不正确，请检查"

    # 校验CIDR格式
    elif mask.isdigit():
        cidr = int(mask)
        if cidr < 0 or cidr > 32:
            return "输入格式不正确，请检查"
    else:
        return "输入格式不正确，请检查"

    try:
        if mask.isdigit():
            # 如果是CIDR格式，转换为点分十进制格式
            cidr = int(mask)
            bin_mask = '1' * cidr + '0' * (32 - cidr)
            parts = [str(int(bin_mask[i:i + 8], 2)) for i in range(0, 32, 8)]
            return '.'.join(parts)
        else:
            # 如果是点分十进制格式，转换为CIDR格式
            parts = mask.split('.')
            bin_mask = ""
            for part in parts:
                bin_mask += bin(int(part))[2:].zfill(8)
            cidr = bin_mask.count('1')
            return str(cidr)
    except:
        return "转换过程出现错误，请检查"


# 测试函数convert_mask
def test_convert_mask():
    """
    测试convert_mask函数的功能正确性，使用多个测试用例进行测试，包括合法和非法的输入。
    """
    test_cases = [
        ("255.255.255.0", "24"),
        ("24", "255.255.255.0"),
        ("256", "输入格式不正确，请检查"),
        ("255.255.255", "输入格式不正确，请检查"),
        ("abc", "输入格式不正确，请检查"),
        ("1.2.3.4.5", "输入格式不正确，请检查"),
        ("-1", "输入格式不正确，请检查"),
        ("33", "输入格式不正确，请检查"),
    ]

    for input_mask, expected_result in test_cases:
        result = convert_mask(input_mask)
        if result == expected_result:
            print(f"测试通过: 对于输入 {input_mask}，返回结果 {result} 符合预期")
        else:
            print(f"测试失败: 对于输入 {input_mask}，预期返回 {expected_result}，实际返回 {result}")

# 测试函数calculate_ip_info
def test_calculate_ip_info():
    """
    测试calculate_ip_info函数的功能正确性，使用多个测试用例进行测试，包括合法和非法的IP地址段输入。
    """
    test_cases = [
        ("192.168.1.10/24", True),
        ("10.0.0.1/8", True),
        ("256.1.1.1/16", False),
        ("1.1.1.1", False),
        ("1.1.1.1/33", False),
        ("1.1.1.1/a", False),
    ]

    for ip_str, expected_result in test_cases:
        result = calculate_ip_info(ip_str)
        if 'error' in result:
            if expected_result:
                print(f"测试失败: 对于输入 {ip_str}，预期正常返回，但实际返回错误信息: {result['error']}")
            else:
                print(f"测试通过: 对于输入 {ip_str}，预期返回错误信息，实际返回: {result['error']}")
        else:
            if expected_result:
                try:
                    # 简单验证返回的各个IP地址对象是否能正常使用（比如打印输出）
                    print("第一个可用地址:", result['first_usable_ip'])
                    print("最后一个可用地址:", result['last_usable_ip'])
                    print("可用地址数量:", result['num_usable_ips'])
                    print("网络地址:", result['network_address'])
                    print("广播地址:", result['broadcast_address'])
                    print(f"测试通过: 对于输入 {ip_str}，返回结果符合预期")
                except Exception as e:
                    print(f"测试失败: 对于输入 {ip_str}，返回结果在验证时出现错误: {str(e)}")
            else:
                print(f"测试失败: 对于输入 {ip_str}，预期返回错误信息，但实际正常返回了结果")

if __name__ == '__main__':
    # 测试convert_mask函数
    # test_convert_mask()

    # 测试calculate_ip_info函数
    # test_calculate_ip_info()
    pass